﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace TfsBacklogMgr.Main
{
    [NotifyPropertyChanged]
    public class User : ViewModelBase
    {

        #region Factory

        protected static Dictionary<int, User> _cache = new Dictionary<int, User>();

        public static User GetUser(int id)
        {
            if (_cache.ContainsKey(id))
                return _cache[id] as User;
            else
                return null;
        }

        public static User GetUser(string login)
        {
            login = login.ToLowerInvariant();
            foreach( var item in _cache )
            {
                if (item.Value.Login.ToLowerInvariant() == login)
                    return item.Value as User;
            }
            return null;
        }

        public static void Add(User newUser)
        {
            if (!_cache.ContainsKey(newUser.Id))
                _cache[newUser.Id] = newUser;
            else
            {
                Remove(newUser.Id);
                _cache[newUser.Id] = newUser;
            }
        }

        public static void Remove(int delUserId)
        {
            if (_cache.ContainsKey(delUserId))
                _cache.Remove( delUserId );
        }

        public static List<User> GetUsers()
        {
            return _cache.Values.ToList();
        }

        #endregion

        private int _Id;
        private bool _IsChosen;
        private string _Name;
        private string _Login;
        private string _ImagePath;
        private BitmapImage _Image;

        private ObservableCollection<WorkItem> _WorkItems;

        public User()
        {
            _WorkItems = new ObservableCollection<WorkItem>();
        }

        public int Id
        {
            get { return _Id; }
            set { _Id =  value; }
        }

        public bool IsChosen
        {
            get { return _IsChosen; }
            set { _IsChosen = value; }
        }

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        public string Login
        {
            get { return _Login; }
            set {  if( _Login != value) _Image = null;
                    _Login = value;
                }
        }

        public string ImagePath
        {
            get { return _ImagePath; }
            set { _Image = null;  _ImagePath = value; OnPropertyChanged("Image"); }
        }
        public BitmapImage Image
        {
            get
            {
                if (_Image != null)
                    return _Image;
                string filename = @"Pictures/unknown-user-icon.png";
                if (File.Exists("Pictures\\" + _Login + ".png"))
                    filename = "Pictures/" + _Login + ".png";
                if (File.Exists("Pictures\\" + _Login + ".jpg"))
                    filename = "Pictures/" + _Login + ".jpg";
                if (File.Exists("Pictures\\" + _Login + ".jpeg"))
                    filename = "Pictures/" + _Login + ".jpeg";

                if (!string.IsNullOrEmpty(_ImagePath) && File.Exists(_ImagePath) )
                    filename = Path.GetFullPath(_ImagePath);

                _Image = new BitmapImage();

                _Image.BeginInit();
                _Image.CacheOption = BitmapCacheOption.OnLoad;
                _Image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                _Image.UriSource = new Uri(filename, UriKind.Relative);
                _Image.EndInit();
                return _Image;
            }
        }

        public IEnumerable<WorkItem> WorkItems 
        { 
            get 
            {
                return _WorkItems;
            } 
        }

        public void UpdateTotals()
        {
            OnPropertyChanged("TotalPoints");
            OnPropertyChanged("TotalHours");
            OnPropertyChanged("TotalRemain");
            OnPropertyChanged("BackgroundColor");
        }

        internal void AddWorkItem(WorkItem w)
        {
            if (w.AssignedTo != this)
                w.AssignedTo = this;
            _WorkItems.Add(w);
            UpdateTotals();
        }

        internal void RemoveWorkItem(WorkItem w)
        {
            _WorkItems.Remove(w);
            UpdateTotals();
        }

        public double TotalPoints
        {
            get
            {
                double sum = 0;
                foreach (var item in _WorkItems)
                    sum += item.Points;
                return sum;
            }
        }

        public double TotalHours
        {
            get
            {
                double sum = 0;
                foreach (var item in _WorkItems)
                    sum += item.Hours;
                return sum;
            }
        }

        public double TotalRemain
        {
            get
            {
                double sum = 0;
                foreach (var item in _WorkItems)
                    sum += item.Remain;
                return sum;
            }
        }

        /// <summary>
        /// Turn the background red if the user is overloaded
        /// </summary>
        public string BackgroundColor
        {
            get
            {
                string result = "#ffffff";
                string grn = "#ddffdd";
                string yel = "#ffffcc";
                string red = "#ffcccc";
                Context ctx = Context.GetContext();
                double cur = TotalRemain;
                if (cur > ctx.MaxRemain * 8 / 10) result = grn;
                if (cur > ctx.MaxRemain * 9 / 10) result = yel;
                if (cur > ctx.MaxRemain * 10 / 10) result = red;
                cur = TotalHours;
                if (cur > ctx.MaxHours * 8 / 10) result = grn;
                if (cur > ctx.MaxHours * 9 / 10) result = yel;
                if (cur > ctx.MaxHours * 10 / 10) result = red;
                cur = TotalPoints;
                if (cur > ctx.MaxPoints * 8 / 10) result = grn;
                if (cur > ctx.MaxPoints * 9 / 10) result = yel;
                if (cur > ctx.MaxPoints * 10 / 10) result = red;
                return result;
            }
        }

        public override string ToString()
        {
            return string.Format("{0} '{1}'", Id, Name);
        }
    }
}
